/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alaeat;

// [START analyticsdata_json_credentials_quickstart]

import com.alaeat.entity.Param;
import com.alaeat.entity.ReportData;
import com.google.analytics.data.v1beta.*;
import com.google.analytics.data.v1beta.Row;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.oauth2.GoogleCredentials;

import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import static com.alaeat.util.Utils.appendDataToExcel;


/**
 * @author cuishidong
 */
public class QuickstartJsonCredentialsSample {
    static String credentialsJsonPath = "config/quickstart-1708588184436.json";
    private static final String[] HEADER = {"Channel Group", "Active Users", "Sessions", "Engaged Sessions", "Average Session Duration", "Sessions Per User", "Events Per Session", "Engagement Rate", "Event Count", "Conversions", "Total Revenue"};

    public static final String SESSION_SOURCE = "sessionSource";
    public static final String SESSION_MEDIUM = "sessionMedium";
    public static final String SESSION_CAMPAIGN_NAME = "sessionCampaignName";
    public static final String OUTPUT_FILEPATH = "./testData.xlsx";

    public static void main(String[] args) throws Exception {

        Scanner scanner = new Scanner(System.in);
        try {
            List<Param> params = readFile("/Users/cuishidong/Workspace/GoogleAnalytics/jar/params.txt");// 调用 readFile 方法读取文件内容
            for (Param param : params) {
                if ("0".equals(param.getType())) {
                    List<ReportData> sessionSource = sampleRunReport(param.getPropertyId(), SESSION_SOURCE, param.getStartTime(), param.getEndTime());
                    appendDataToExcel(OUTPUT_FILEPATH, param.getPropertyId(), SESSION_SOURCE, HEADER, sessionSource);
                    sessionSource = sampleRunReport(param.getPropertyId(), SESSION_MEDIUM, param.getStartTime(), param.getEndTime());
                    appendDataToExcel(OUTPUT_FILEPATH, param.getPropertyId(), SESSION_MEDIUM, HEADER, sessionSource);
                    sessionSource = sampleRunReport(param.getPropertyId(), SESSION_CAMPAIGN_NAME, param.getStartTime(), param.getEndTime());
                    appendDataToExcel(OUTPUT_FILEPATH, param.getPropertyId(), SESSION_CAMPAIGN_NAME, HEADER, sessionSource);

                }
                if (param.getType().contains("1")) {
                    List<ReportData> sessionSource = sampleRunReport(param.getPropertyId(), SESSION_SOURCE, param.getStartTime(), param.getEndTime());
                    appendDataToExcel(OUTPUT_FILEPATH, param.getPropertyId(), SESSION_SOURCE, HEADER, sessionSource);
                }
                if (param.getType().contains("2")) {
                    List<ReportData> sessionSource = sampleRunReport(param.getPropertyId(), SESSION_MEDIUM, param.getStartTime(), param.getEndTime());
                    appendDataToExcel(OUTPUT_FILEPATH, param.getPropertyId(), SESSION_MEDIUM, HEADER, sessionSource);
                }
                if (param.getType().contains("3")) {
                    List<ReportData> sessionSource = sampleRunReport(param.getPropertyId(), SESSION_CAMPAIGN_NAME, param.getStartTime(), param.getEndTime());
                    appendDataToExcel(OUTPUT_FILEPATH, param.getPropertyId(), SESSION_CAMPAIGN_NAME, HEADER, sessionSource);
                }

            }
            System.out.println("SUCCESS!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            scanner.close(); // 关闭 Scanner 对象
        }


    }

    public static List<ReportData> sampleRunReport(String propertyId, String dimension, String startTime, String endTime) throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        InputStream in = classLoader.getResourceAsStream(credentialsJsonPath);

        GoogleCredentials credentials =
                GoogleCredentials.fromStream(in);

        BetaAnalyticsDataSettings betaAnalyticsDataSettings =
                BetaAnalyticsDataSettings.newBuilder()
                        .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
                        .build();

        try (BetaAnalyticsDataClient analyticsData =
                     BetaAnalyticsDataClient.create(betaAnalyticsDataSettings)) {
            RunReportRequest request =
                    RunReportRequest.newBuilder()
                            .setProperty("properties/" + propertyId)
                            .addDimensions(Dimension.newBuilder().setName(dimension))
                            .addMetrics(Metric.newBuilder().setName("activeUsers"))
                            .addMetrics(Metric.newBuilder().setName("sessions"))
                            .addMetrics(Metric.newBuilder().setName("engagedSessions"))
                            .addMetrics(Metric.newBuilder().setName("averageSessionDuration"))//
                            .addMetrics(Metric.newBuilder().setName("sessionsPerUser"))//
                            .addMetrics(Metric.newBuilder().setName("eventsPerSession"))
                            .addMetrics(Metric.newBuilder().setName("engagementRate"))
                            .addMetrics(Metric.newBuilder().setName("eventCount"))
                            .addMetrics(Metric.newBuilder().setName("conversions"))
                            .addMetrics(Metric.newBuilder().setName("totalRevenue"))
                            .addDateRanges(DateRange.newBuilder().setStartDate(startTime).setEndDate(endTime))
                            .build();

            // Make the request.
            System.out.println("Downloading " + propertyId + " dimension:" + dimension + " data............");
            RunReportResponse response = analyticsData.runReport(request);
            List<ReportData> dataArrayList = new ArrayList<>();
            for (Row row : response.getRowsList()) {
                ReportData reportData = new ReportData(
                        row.getDimensionValues(0).getValue(),
                        row.getMetricValues(0).getValue(),
                        row.getMetricValues(1).getValue(),
                        row.getMetricValues(2).getValue(),
                        row.getMetricValues(3).getValue(),
                        row.getMetricValues(4).getValue(),
                        row.getMetricValues(5).getValue(),
                        row.getMetricValues(6).getValue(),
                        row.getMetricValues(7).getValue(),
                        row.getMetricValues(8).getValue(),
                        row.getMetricValues(9).getValue());
                dataArrayList.add(reportData);
            }
            System.out.println(propertyId + "dimension:" + dimension + " Data writing is complete。");
            return dataArrayList;
        }
    }

    static void appendToFile(String filePath, String dataToAppend) throws IOException {
        try (FileWriter fileWriter = new FileWriter(filePath, true)) {
            fileWriter.write(dataToAppend);
        }
    }

    // 读取文件内容的方法
    static List<Param> readFile(String filePath) throws IOException {
        List<Param> params = new ArrayList<>();
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                String[] parts = line.split(",");
                Param param = new Param(parts[0], parts[1], parts[2], parts[3]);
                params.add(param);
            }
        }
        return params;
    }


}

